package threads;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;

import model.Preference;
import model.Settings;
import net.HttpRequestFacade;
import platform.PlatformObjectFactory;
import util.EmailSending;
import util.LoggingUtils;

public class PlayerMonitor implements Runnable {

	private List<Thread> threads; // the threads being monitored
	//RBB start
	// date is compared to currentDate in run() method to check if a new day has
	// started (after midnight) so that a new FileHandler can be assigned to 
	// the Logger defined in LoggingUtils to create a new log file with a new 
	// date in its filename.
	private String date;
	private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
	protected final String className = this.getClass().getName();
	//RBB end

	public PlayerMonitor() {
		this.threads = new ArrayList<Thread>();
		date = simpleDateFormat.format(new Date());
	}

	@Override
	public void run() {
		final String classMethod = className + ".run()";
		LoggingUtils.logStart(classMethod);
		//System.out.println("== Starting Monitoring Thread: Inside for checking");
		while (true) {
			for (Thread thread : this.threads) {
				if (!thread.isAlive()) {
					LoggingUtils.log(Level.SEVERE, "Thread " + thread.getName() + " is not alive in " + classMethod);
					System.out.println(thread.getName() + " is dead.. restart player.");
					
					/* Sending exception to server */
					HttpRequestFacade.postPlayerException("Critical", "Thread " + thread.getName() + " is not alive in " + classMethod,"Restart");
					
					// Mailing the error 
					String EmailBody = EmailSending.ProcessEmailBody(thread.getName() + " is dead.. restart player.", 
																"Restarting:MonitoringThread", thread.getName() + " is dead in "+classMethod);
					
					util.EmailSending.getInstance().send(Settings.TO_USER, "Restarting:MonitoringThread:" +
							"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
					
					PlatformObjectFactory.getInstance().getCommandExecutor().restartPlayer();
				}
				
				//System.out.println("######### Monitoring Thread "+thread.getName()+"################");
			}
			try {
				Thread.sleep(60 * 1000);
				//RBB start
				// TODO :todo Check we Yang if there is not a better place to do a check for new day.
				// When a new day has started (after midnight) increment the date in the Logger
				// filename to the new day.
				String currentDate = simpleDateFormat.format(new Date());
				if (currentDate.compareTo(date) > 0) {
					LoggingUtils.incrementDateInLogName();
					date = currentDate;
				}
				//RBB start
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				LoggingUtils.log(Level.SEVERE, "Thread.sleep interrupted in " + classMethod,e);
				e.printStackTrace();
			}
			catch (Exception e) {
				 LoggingUtils.log(Level.SEVERE, " in " + classMethod,e);
			}
		}
	}

	public void addThread(Thread thread) {
		this.threads.add(thread);
	}

}
